﻿using Extended.WPF.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace Extented.UI.Core.Helpers
{
    public static class FrameworkElementHelper
    {
        public static readonly DependencyProperty IsMouseOverOverrideProperty =
            DependencyProperty.RegisterAttached("IsMouseOverOverride", typeof(bool), typeof(FrameworkElementHelper),
                new PropertyMetadata((o, e) => OnIsMouseOverOverrideChanged((FrameworkElement)o)));
        public static readonly DependencyProperty EnableIsMouseOverOverrideProperty =
            DependencyProperty.RegisterAttached("EnableIsMouseOverOverride", typeof(bool), typeof(FrameworkElementHelper),
                new PropertyMetadata((o, e) => OnEnableIsMouseOverOverrideChanged((FrameworkElement)o, (bool)e.NewValue)));
        public static readonly DependencyProperty ClipCornerRadiusProperty =
            DependencyProperty.RegisterAttached("ClipCornerRadius", typeof(double), typeof(FrameworkElementHelper),
                new PropertyMetadata((o, e) => OnClipCornerRadiusChanged((FrameworkElement)o)));
        public static readonly DependencyProperty IsClippedProperty =
            DependencyProperty.RegisterAttached("IsClipped", typeof(bool), typeof(FrameworkElementHelper),
                new PropertyMetadata(
                    delegate(DependencyObject o, DependencyPropertyChangedEventArgs e)
                    {
                        var element = o as FrameworkElement;
                        if (element == null)
                            return;
                        if ((bool)e.NewValue)
                            element.SizeChanged += OnElementSizeChanged;
                        else
                            element.SizeChanged -= OnElementSizeChanged;
                    }));
        public static readonly DependencyProperty IsVisibleProperty =
            DependencyProperty.RegisterAttached("IsVisible", typeof(bool), typeof(FrameworkElementHelper),
                new PropertyMetadata(true, (o, e) => ((FrameworkElement)o).SetVisible((bool)e.NewValue)));
        public static object GetToolTip(FrameworkElement element)
        {
            return element.ToolTip;
        }
        public static void SetToolTip(FrameworkElement element, object value)
        {
            element.ToolTip = value;
        }
        public static void SetIsLoaded(FrameworkElement element, bool isLoaded)
        {
        }
        public static bool GetIsLoaded(FrameworkElement element)
        {
            return element.IsLoaded;
        }
        public static void SetIsLoaded(FrameworkContentElement element, bool isLoaded)
        {
        }
        public static bool GetIsLoaded(FrameworkContentElement element)
        {
            return element.IsLoaded;
        }
        public static void SetAllowDrop(FrameworkElement element, bool allowDrop)
        {
            element.AllowDrop = allowDrop;
        }
        public static bool GetAllowDrop(FrameworkElement element)
        {
            return element.AllowDrop;
        }
        public static double GetClipCornerRadius(FrameworkElement element)
        {
            return (double)element.GetValue(ClipCornerRadiusProperty);
        }
        public static void SetClipCornerRadius(FrameworkElement element, double value)
        {
            element.SetValue(ClipCornerRadiusProperty, value);
        }
        public static bool GetIsClipped(FrameworkElement element)
        {
            return (bool)element.GetValue(IsClippedProperty);
        }
        public static void SetIsClipped(FrameworkElement element, bool value)
        {
            element.SetValue(IsClippedProperty, value);
        }
        public static bool GetIsMouseOverOverride(FrameworkElement element)
        {
            return (bool)element.GetValue(IsMouseOverOverrideProperty);
        }
        public static void SetIsMouseOverOverride(FrameworkElement element, bool value)
        {
            element.SetValue(IsMouseOverOverrideProperty, value);
        }
        public static bool GetEnableIsMouseOverOverride(FrameworkElement element)
        {
            return (bool)element.GetValue(EnableIsMouseOverOverrideProperty);
        }
        public static void SetEnableIsMouseOverOverride(FrameworkElement element, bool value)
        {
            element.SetValue(EnableIsMouseOverOverrideProperty, value);
        }
        public static bool GetIsVisible(FrameworkElement element)
        {
            return element.GetVisible();
        }
        public static void SetIsVisible(FrameworkElement element, bool value)
        {
            element.SetValue(IsVisibleProperty, value);
        }
        private static void OnClipCornerRadiusChanged(FrameworkElement element)
        {
            element.SizeChanged -= ElementClipCornerRadiusSizeChanged;
            element.SizeChanged += ElementClipCornerRadiusSizeChanged;
            ElementClipCornerRadiusSizeChanged(element, null);
        }
        static void ElementClipCornerRadiusSizeChanged(object sender, SizeChangedEventArgs e)
        {
            FrameworkElement element = (FrameworkElement)sender;
            double radius = GetClipCornerRadius(element);
            element.Clip = new RectangleGeometry { Rect = RectHelper.New(new Size(element.ActualWidth, element.ActualHeight)), RadiusX = radius, RadiusY = radius };
        }
        private static void OnElementSizeChanged(object sender, SizeChangedEventArgs e)
        {
            ((FrameworkElement)sender).ClipToBounds();
        }
        private static void OnEnableIsMouseOverOverrideChanged(FrameworkElement frameworkElement, bool value)
        {
            MouseEventHandler enter = new MouseEventHandler((d, e) => { frameworkElement.SetValue(IsMouseOverOverrideProperty, true); });
            MouseEventHandler leave = new MouseEventHandler((d, e) => { frameworkElement.SetValue(IsMouseOverOverrideProperty, false); });
            if (value)
            {
                frameworkElement.MouseEnter += enter;
                frameworkElement.MouseLeave += leave;
            }
            else
            {
                frameworkElement.MouseEnter -= enter;
                frameworkElement.MouseLeave -= leave;
            }
        }
        private static void OnIsMouseOverOverrideChanged(FrameworkElement frameworkElement)
        {
        }
    }
}
